package com.atguigu.gulimall.auth.controller;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.constant.AuthServerConstant;
import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.common.to.MemberEntityVo;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.auth.feign.MemberFeignService;
import com.atguigu.gulimall.auth.feign.ThirdPartFeignService;
import com.atguigu.gulimall.auth.vo.UserLoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
public class LoginController {
    @Autowired
    private ThirdPartFeignService thirdPartFeignService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MemberFeignService memberFeignService;

    @ResponseBody
    @GetMapping("/sms/sendCode")
    public R sendCode(@RequestParam String phone) {
        // 接口防刷
        String key = AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone;
        String redisCode = redisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(redisCode)) {
            long oldCodeTime = Long.parseLong(redisCode.split("_")[1]);
            if (System.currentTimeMillis() - oldCodeTime < 60 * 1000) {
                // 60秒内不能再发
                return R.error(BizCodeEnume.VAILD_SMS_CODE_EXCEPTION);
            }
        }

        // 验证码sms:code:15827214096_15764812663 -> 4567
        String code = UUID.randomUUID()
                .toString()
                .replaceAll("-", "")
                .substring(0, 5);

        // 验证码缓存起来 防止同一个phone在过期时间内再次发送
        redisTemplate.opsForValue().set(key, code + "_" + System.currentTimeMillis(), 10, TimeUnit.MINUTES);

        // 发送验证码
        thirdPartFeignService.sendSms(phone, code);
        return R.ok();
    }

    @GetMapping("/login.html")
    public String loginPage(@RequestParam(required = false) String originUrl,
                            Model model,
                            HttpSession session) {
        Object loginUser = session.getAttribute(AuthServerConstant.LOGIN_USER);
        if (loginUser == null) {
            //没登陆
            if (!StringUtils.isEmpty(originUrl)) {
                model.addAttribute("originUrl", originUrl);
            }
            return "login";
        } else {
            // 已经登陆过了
            if (!StringUtils.isEmpty(originUrl)) {
                return "redirect:" + originUrl;
            } else {
                return "redirect:http://gulimall.com";
            }
        }
    }

    @PostMapping("/login")
    public String login(UserLoginVo loginVo, RedirectAttributes redirectAttributes, HttpSession session) {
        R r = memberFeignService.login(loginVo);
        if (r.getCode() == 0) {
            // 登录成功
            session.setAttribute(AuthServerConstant.LOGIN_USER, r.getData(new TypeReference<MemberEntityVo>() {
            }));
            if (!StringUtils.isEmpty(loginVo.getOriginUrl())) {
                return "redirect:" + loginVo.getOriginUrl();
            } else {
                return "redirect:http://gulimall.com";
            }
        } else {
            redirectAttributes.addFlashAttribute(
                    "errors",
                    MapUtil.builder()
                            .put("msg", r.getData("msg", new TypeReference<String>() {
                            }))
                            .map()
            );
            return "redirect:http://auth.gulimall.com/login.html";
        }
    }
}
